package tagdb.ui;

import com.jgoodies.forms.layout.CellConstraints;
import com.jgoodies.forms.layout.FormLayout;
import org.jdesktop.swingx.JXTable;
import org.jdesktop.swingx.JXTitledPanel;
import tagdb.algorithm.factory.MutationFactory;
import tagdb.model.Mutation;
import tagdb.ui.util.PanelFactory;
import tagdb.ui.util.TableConfig;

import javax.swing.*;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.JTableHeader;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.List;


public class MutationsDialog extends JDialog {


    private MainFrame mainFrame;

    /**
     * The mutations factory.
     */
    private List<Mutation> mutations = MutationFactory.createMutations();

    /**
     * Mutations scroll pane.
     */
    private JScrollPane mutationsScp;

    /**
     * The mutations table.
     */
    private JXTable mutationsTbl;

    private ArrayList<String> mutationsTableToolTips;
    private JButton closeBtn;

    public MutationsDialog(MainFrame mainFrame) {
        this.mainFrame = mainFrame;
        initComponents();
        setModal(true);
    }

    private void initComponents() {
        // Cell constraints.
        CellConstraints cc = new CellConstraints();
        this.setLayout(new FormLayout("5dlu, p:g, 5dlu", "5dlu, t:p:g, 5dlu, t:p:g  "));

        mutationsScp = new javax.swing.JScrollPane();
        mutationsTbl = new JXTable() {
            protected JTableHeader createDefaultTableHeader() {
                return new JTableHeader(columnModel) {
                    public String getToolTipText(MouseEvent e) {
                        Point p = e.getPoint();
                        int index = columnModel.getColumnIndexAtX(p.x);
                        int realIndex = columnModel.getColumn(index).getModelIndex();
                        return (String) mutationsTableToolTips.get(realIndex);
                    }
                };
            }
        };
        mutationsTbl.setModel(new DefaultMutationsTableModel());
        mutationsTbl.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);

        mutationsScp.setViewportView(mutationsTbl);
        mutationsScp.setPreferredSize(new Dimension(800, 270));
        JXTitledPanel mutationTtlPnl = PanelFactory.createTitledPanel("Mutations", mutationsScp);

        setupTable();

        closeBtn = new JButton();
        closeBtn.setText("Close");
        closeBtn.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                dispose();
            }
        });
        JPanel bottomPnl = new JPanel(new BorderLayout());
        JPanel buttonPnl = new JPanel(new FormLayout("5dlu, p, 5dlu", "5dlu, p, 5dlu"));
        buttonPnl.add(closeBtn, cc.xy(2, 2));
        bottomPnl.add(buttonPnl, BorderLayout.EAST);
        this.add(mutationTtlPnl, cc.xy(2, 2));
        this.add(bottomPnl, cc.xy(2, 4));

        pack();
        setLocationRelativeTo(getOwner());
        setResizable(false);
        setVisible(true);
    }

    /**
     * Set up the table properties.
     */
    private void setupTable() {

        mutationsTbl.setAutoCreateRowSorter(true);

        // make sure that the scroll panes are see-through
        mutationsScp.getViewport().setOpaque(false);

        mutationsTbl.getTableHeader().setReorderingAllowed(false);

        // Selection background
        mutationsTbl.setSelectionBackground(TableConfig.ROW_SELECTION_BACKGROUND_COLOR);

        // Add striping effect
        mutationsTbl.addHighlighter(TableConfig.getSimpleStriping());

        // the index column
        mutationsTbl.getColumn("#").setMaxWidth(40);
        mutationsTbl.getColumn("#").setMinWidth(40);
        mutationsTbl.getColumn("Type").setMaxWidth(100);
        mutationsTbl.getColumn("Type").setMinWidth(100);


        // set up the ptm type color map
       // HashMap<Integer, Color> ptmTypeColorMap = ModificationFile.getColorTypeMap();


        //TODO: mutationsTbl.getColumn("Type").setCellRenderer(new JSparklinesIntegerColorTableCellRenderer(Color.lightGray, ptmTypeColorMap, ptmTypeTooltipMap));


        // set up the table header tooltips
        mutationsTableToolTips = new ArrayList<String>();
        mutationsTableToolTips.add(null);
        mutationsTableToolTips.add("Mutation Origin Amino Acid");
        mutationsTableToolTips.add("Mutation Target Amino Acid");
        mutationsTableToolTips.add("Mutation Mass Shift");
        mutationsTableToolTips.add("Mutation Type");
    }

    /**
     * Table model for the default mods table.
     */
    private class DefaultMutationsTableModel extends DefaultTableModel {

        @Override
        public int getRowCount() {
            return mutations.size();
        }

        @Override
        public int getColumnCount() {
            return 5;
        }

        @Override
        public String getColumnName(int column) {
            switch (column) {
                case 0:
                    return "#";
                case 1:
                    return "Origin";
                case 2:
                    return "Target";
                case 3:
                    return "Mass Shift";
                case 4:
                    return "Type";
                default:
                    return "";
            }
        }

        @Override
        public Object getValueAt(int row, int column) {
            Mutation mutation = mutations.get(row);
            switch (column) {
                case 0:
                    return row + 1;
                case 1:
                    return mutation.getOrigin().singleLetterCode + "(" + mutation.getOrigin().threeLetterCode + ")";
                case 2:
                    return mutation.getTarget().singleLetterCode + "(" + mutation.getTarget().threeLetterCode + ")";
                case 3:
                    return mutation.getMassShift();
                case 4:
                    return ""; //TODO: Type!
                default:
                    return "";
            }
        }

        @Override
        public Class getColumnClass(int columnIndex) {
            for (int i = 0; i < getRowCount(); i++) {
                if (getValueAt(i, columnIndex) != null) {
                    return getValueAt(i, columnIndex).getClass();
                }
            }
            return (new Double(0.0)).getClass();
        }

        @Override
        public boolean isCellEditable(int rowIndex, int columnIndex) {
            return false;
        }
    }
}
